<?php
/*
 * DisplayOrderList snippet
 *
 * Possible parameters:
 * 	sort_by: Which column to sort the results by (default: transaction_date)
 * 	start: Which result to start with (default: 0)
 * 	many: How many results to return (default: 25)
 */	

// Set Paths
$mod_path = $modx->config['base_path'] . 'assets/modules/foxyback/';
include_once $mod_path.'config.inc.php';
include_once $mod_path.'foxyback.class.inc.php';
include_once $mod_path.'pagination.inc.php';
include_once $mod_path.'functions.inc.php';

// Initialize the FoxyBack object.
$foxyback = new FoxyBack();

// Determine if the current user is a manager or not.
$is_manager = true;
if ($is_user) {
	$is_manager = false;
}

// Information about this web user is stored in the session.
if ($is_user && !isset($_SESSION['web_user_customer_id'])) {
	// Look up the customer id for this user.
	$email = $modx->getLoginUserName();
	//print "got login username: '$email'";
	if (!$customer_view = $foxyback->getCustomerViewOnEmail($email)) {
		// No customer has that email address - this user cannot be here.
		$url = $modx->makeUrl(1);
		ob_end_clean();
		header('Location: '.$url);
	}

	$_SESSION['web_user_customer_id'] = $customer_view['customer_id'];
	//print "Got customer id: ".$customer_view['customer_id'];
}

$web_user_customer_id = $_SESSION['web_user_customer_id'];


// Any of these can be set in the snippet call or via parameters.
$tpl;
$debug;
$sort_by;
$many;
$page;
$search_order_status;
$search_flagged;
$search_start_date;
$search_end_date;
$search_custom_date;
$global_search;

// The "name" of this snippet changes depending on whether the user is a manager or a customer/webuser.
$snippet_name = 'UserDisplayOrderList';
if ($is_manager) {
	$snippet_name = 'DisplayOrderList';
}

// Parse the config file.
if (isset($SNIPPET_CONFIG) && is_array($SNIPPET_CONFIG) && is_array($SNIPPET_CONFIG[$snippet_name])) {
	$config = $SNIPPET_CONFIG[$snippet_name];

	if (!isset($tpl) && isset($config['tpl'])) {
		$tpl = $config['tpl'];
	}
	if (!isset($sort_by) && isset($config['sort_by'])) {
		$sort_by = $config['sort_by'];
	}
	if (!isset($many) && isset($config['many'])) {
		$many = $config['many'];
	}
	if (!isset($page) && isset($config['page'])) {
		$page = $config['page'];
	}
	if (!isset($search_order_status) && isset($config['search_order_status'])) {
		$search_order_status = $config['search_order_status'];
	}
	if (!isset($search_flagged) && isset($config['search_flagged'])) {
		$search_flagged = $config['search_flagged'];
	}
	if (!isset($search_start_date) && isset($config['search_start_date'])) {
		$search_start_date = $config['search_start_date'];
	}
	if (!isset($search_end_date) && isset($config['search_end_date'])) {
		$search_end_date = $config['search_end_date'];
	}
	if (!isset($search_custom_date) && isset($config['search_custom_date'])) {
		$search_custom_date = $config['search_custom_date'];
	}
	if (!isset($global_search) && isset($config['global_search'])) {
		$global_search = $config['global_search'];
	}
	if (!isset($debug) && isset($config['debug'])) {
		$debug = $config['debug'];
	}

	unset($config);
}

// Get the templates/chunks to use.
// template_name:chunk_name|
if (!isset($tpl)) {
	$tpl = 'manager_form:ManagerForm|order_row:OrderRow|detail_row:DetailRow|message_success:MessageSuccess|message_error:MessageError';
}
$tpl_array = explode('|', $tpl);
foreach ($tpl_array as $template) {
	list($tpl_name, $chunk_name) = explode(':', $template, 2);
	switch($tpl_name) {
	case 'manager_form':
		$manager_form_tpl = $chunk_name;
		break;
	case 'order_row':
		$order_row_tpl = $chunk_name;
		break;
	case 'detail_row':
		$detail_row_tpl = $chunk_name;
		break;
	case 'message_success':
		$message_success_tpl = $chunk_name;
		break;
	case 'message_error':
		$message_error_tpl = $chunk_name;
		break;
	}
}

// Set defaults for the parameters.
$debug = ($_REQUEST['debug']) ? $_REQUEST['debug'] : $debug;

if (isset($_REQUEST['sort_by'])) { $sort_by = $_REQUEST['sort_by']; }
// set default
elseif ($sort_by == '') { $sort_by = 'transaction_date DESC'; }

if (isset($_REQUEST['many'])) { $many = $_REQUEST['many']; }
elseif ($many == '') { $many = 25; }

if (isset($_REQUEST['page'])) { $page = $_REQUEST['page']; }
elseif ($page == '') { $page = 1; }

if (isset($_REQUEST['search_order_status'])) { $search_order_status = $_REQUEST['search_order_status']; }
if (isset($_REQUEST['search_flagged'])) { $search_flagged = $_REQUEST['search_flagged']; }
if (isset($_REQUEST['search_start_date'])) { $search_start_date = $_REQUEST['search_start_date']; }
if (isset($_REQUEST['search_end_date'])) { $search_end_date = $_REQUEST['search_end_date']; }
if (isset($_REQUEST['search_custom_date'])) { $search_custom_date = $_REQUEST['search_custom_date']; }
if (isset($_REQUEST['global_search'])) { $global_search = $_REQUEST['global_search']; }

// ==================================================================
// Process any page actions.
// ==================================================================

// Holder for confirmation or error messages.
$page_message = '';

// Perform a bulk edit.
$bulk_edit_result = '';
if ($is_manager && $_REQUEST['bulk_order_status'] > 0) {
	$new_status = $_REQUEST['bulk_order_status'];
	$edit_count = 0;
	// Include the notes on each update.
	$status_notes = $_REQUEST['bulk_status_notes'];
	// Find all of the boxes that are checked.
	foreach ($_REQUEST as $param_name => $param_value) {
		if (preg_match("/^(\d+)-action_checkbox$/", $param_name, $matches)) {
			$trans_id = $matches[1];
			if (!$update_id = $foxyback->editTransaction($trans_id, array('order_status_id' => $new_status, 'status_notes' => $status_notes))) {
				// Error
				$bulk_edit_result .= "<p>Error on transaction $trans_id: ".$foxyback->error_info."</p>\n";
			}
			else {
				$edit_count++;
			}
		}
	}
	if ($edit_count > 0) {
		$page_message = formatMessage('Successfully edited the status on '.$edit_count.' transactions.', $message_success_tpl);
	}
	if ($bulk_edit_result != '') {
		$page_message .= formatMessage("The following transactions had errors: ".$bulk_edit_result, $message_error_tpl);
	}
}

// ==================================================================
// Prepare the filter for the list function.
// ==================================================================

// Determine the start based on the page.
$page_offset = (is_numeric($page) && $page > 0) ? $page - 1 : 0;
$start = ($page_offset * $many);

// Build the filter based on the search criteria.
// filter = clause|clause|clause
// clause = field,criterion,mode
$filter = '';

// These are based on the Ditto filter modes, except they are used to INCLUDE, 
// not exclude, transactions.
$comparison_modes = array(
	'!=' 			=> 1,
	'==' 			=> 2,
	'<' 			=> 3,
	'>' 			=> 4,
	'<='			=> 5,
	'>='			=> 6,
	'NOT CONTAIN' 	=> 7,
	'CONTAIN'		=> 8,
);

if (!$is_manager && $web_user_customer_id > 0) {
	// Restrict to this customer only.
	$filter .= '|customer_id,'.$web_user_customer_id.','.$comparison_modes['=='];
}

if ($search_order_status != '') {
	$filter .= '|order_status_id,'.$search_order_status.','.$comparison_modes['=='];
}

// Calculate custom date options
if ($search_custom_date == 'day_last_7') {
	$search_start_date = date('Y-m-d', time() - (86400 * 7));
}
elseif ($search_custom_date == 'day_last_14') {
	$search_start_date = date('Y-m-d', time() - (86400 * 14));
}
elseif ($search_custom_date == 'day_last_30') {
	$search_start_date = date('Y-m-d', time() - (86400 * 30));
}
elseif ($search_custom_date == 'month_current') {
	// Find the first day of the month.
	$date = date('Y-m-d', time());
	$search_start_date = preg_replace("/-\d\d$/", "-01", $date);
}
elseif ($search_custom_date == 'month_last_1') {
	// Find the first day of the current month for the end date..
	$date = date('Y-m-d', time());
	$search_end_date = preg_replace("/-\d\d$/", "-01", $date);
	// Subtract a month from that.
	list($year, $month, $day) = explode('-', $search_end_date);
	$month--;
	// Adjust for year wrapping.
	if ($month == '0') {
		$month = 12;
		$year--;
	}
	$search_start_date = "$year-$month-$day";
}

// Default the end date to today.
if ($search_end_date == '') {
	$search_end_date = date('Y-m-d', time());
}

// Handle the default search options.
if (1==2 && $_REQUEST['search'] == '') {
	// Do not set a default status.
	//$search_order_status = $foxyback->getStatusIdByName($DEFAULT_ORDER_STATUS);
	//$filter .= '|order_status_id,'.$search_order_status.','.$comparison_modes['=='];

	// Default the date to the last 7 days.
	if ($search_start_date == '') {
		$search_start_date = date('Y-m-d', time() - (86400 * 7));
	}
}

if ($search_flagged != '') {
	$filter .= '|flagged,'.$search_flagged.','.$comparison_modes['=='];
}

// Create the date filters.
if ($search_start_date != '') {
	$filter .= '|transaction_date,'.$search_start_date.','.$comparison_modes['>='];
}
if ($search_end_date != '') {
	// Push this out to the next day, so the search will include the entire day selected.
	// TODO: doesn't work for DST
	$timestamp = strtotime($search_end_date) + 86400;
	$adjusted_end_date = date('Y-m-d', $timestamp);
	$filter .= '|transaction_date,'.$adjusted_end_date.','.$comparison_modes['<'];
}

// Call backend function to return an array of transactions based on our limit.
$search_array = array(
	'filter' => $filter,
	'global_search' => $global_search,
);
$transaction_array = $foxyback->getTransactionList($search_array, $sort_by, $start, $many);

if ($debug) {
	print 'transaction array: '; print_r($transaction_array); print '';
	return;
}

// Get the list of statuses for display purposes.
$status_list = $foxyback->getStatusList();

// ==================================================================
// Generate the page.
// ==================================================================

// List of field names that can be directly added as placeholders without any modification.
$transaction_fields = array(
	'transaction_id', 'transaction_datetime', 'transaction_date', 'transaction_time', 
	'purchase_order', 'order_status_id', 'order_status', 'flagged', 
	'product_total', 'tax_total', 'shipping_total', 'order_total', 'rma_number', 
	'ship_tracking_number', 'ship_reference_number', 'ship_method', 
	'ship_datetime', 'ship_date', 'ship_time', 
	'customer_id', 'email', 'ip_address', 'password', 'address_id', 
	'customer_name', 'first_name', 'last_name', 'company', 'address1', 'address2', 'city', 'state', 
	'postal_code', 'country', 'phone',
);

$detail_fields = array(
	'transaction_detail_id', 'transaction_id', 'product_name', 'product_price', 'product_quantity', 
	'product_weight', 'product_code', 'subscription_frequency', 'subscription_startdate', 
	'next_transaction_date', 'shipto', 'category_description', 'category_code', 'product_delivery_type', 
);

$shipto_fields = array(
	'address_id', 'transaction_id', 'first_name', 'last_name', 'address1', 'address2', 'city', 'state', 
	'postal_code', 'country', 'phone', 'service_description', 'subtotal', 'tax_total', 'shipping_total', 'total',
);

// Template handling based on the transaction array.
// Format each individual row.
$order_rows_output = '';
foreach ($transaction_array['LIST'] as $transaction) {
	// Get the necessary values.
	$transaction_id = $transaction['transaction_id'];
	$customer_id = $transaction['customer_id'];

	// Placeholders are held in a global array and are not merged with the page content until the final rendering.
	// Since each one must be unique, prepend a unique id to each one.
	// Note: colons are not allowed inside placeholders, so use a dash instead.
	$unique_id = 'transaction'.$transaction_id;
	$modx->setPlaceholder($unique_id.'-country_lowercase', strtolower($transaction['country']));

	foreach ($transaction_fields as $fieldname) {
		$modx->setPlaceholder($unique_id.'-'.$fieldname, $transaction[$fieldname]);
	}

	// Set a placeholder to show/hide a 'flagged' icon.
	$flagged_hide_style = '';
	if ($transaction['flagged'] == 'NO') {
		$flagged_hide_style = 'display:none; ';
	}
	$modx->setPlaceholder($unique_id.'-flagged_hide_style', $flagged_hide_style);

	if (!$transaction['transaction_details'])	// skip past transactions without details, e.g., customer address updates.
		continue;

	// Create a summary of the products/details in this transaction.
	$detail_rows_output = '';
	foreach ($transaction['transaction_details'] as $detail) {
		$detail_unique_id = $unique_id . '-' . $detail_id;

		// Set the placeholders.
		foreach ($detail_fields as $fieldname) {
			$modx->setPlaceholder($detail_unique_id.'-'.$fieldname, $detail[$fieldname]);
		}

		$detail_chunk = $modx->getChunk($detail_row_tpl);
		$detail_chunk = preg_replace("/\[\+/", "[+$detail_unique_id".'-', $detail_chunk);

		$detail_rows_output .= $detail_chunk;
	}
	$modx->setPlaceholder($unique_id.'-detail_rows', $detail_rows_output);

	// Generate the order status select box.
	$status_options = '';
	foreach ($status_list as $status) {
		$selected = ($status['status_id'] == $transaction['order_status_id']) ? 'selected="selected"' : '';
		$status_options .= '<option value="'.$status['status_id'].'" '.$selected.'>';
		$status_options .= $status['name']."</option>\n";
	}
	$modx->setPlaceholder($unique_id.'-order_status_options', $status_options);

	// Display the first shipto address.
	// TODO: Figure out how to display multiship here.
	if (array_key_exists('shipto_addresses', $transaction) && is_array($transaction['shipto_addresses'])) {
		$address = $transaction['shipto_addresses'][0];

		foreach ($shipto_fields as $fieldname) {
			$modx->setPlaceholder($unique_id.'-shipto_address-'.$fieldname, $address[$fieldname]);
		}
	}

	// Append the unique id to the beginning of each placeholder in the order chunk.
	$chunk = $modx->getChunk($order_row_tpl);
	$chunk = preg_replace("/\[\+/", "[+$unique_id".'-', $chunk);

	// Output the chunk for this order.
	$order_rows_output .= $chunk;
}

// The following fields are only available for managers (NOT web users).
if ($is_manager) {
	// Generate the various order status select boxes.
	$search_status_options = '<option value="">:: Choose ::</option>';
	$bulk_status_options = '<option value="">:: Choose ::</option>';
	foreach ($status_list as $status) {
		$status_id = $status['status_id'];
		$name = $status['name'];
		$selected = ($status_id == $search_order_status) ? 'selected="selected"' : '';

		$search_status_options .= "<option value=\"$status_id\" $selected>$name</option>\n";
		$bulk_status_options .= "<option value=\"$status_id\">$name</option>\n";
	}

		$modx->setPlaceholder('bulk_order_status_options', $bulk_status_options);
		$modx->setPlaceholder('search_order_status_options', $search_status_options);

	$search_custom_date_options = <<<EOT
	<option value="">:: custom date ::</option>
	<option value="day_last_7">last 7 days</option>
	<option value="day_last_14">last 14 days</option>
	<option value="day_last_30">last 30 days</option>
	<option value="month_current">this month</option>
	<option value="month_last_1">last month</option>
EOT;
	$modx->setPlaceholder('search_custom_date_options', $search_custom_date_options);

	$modx->setPlaceholder('global_search', $global_search);
	$modx->setPlaceholder('search_start_date', $search_start_date);
	$modx->setPlaceholder('search_end_date', $search_end_date);

	if ($search_flagged == 'YES') {
		$search_flagged_checked = 'checked="checked"';
	}
	$modx->setPlaceholder('search_flagged_checked', $search_flagged_checked);
}

$modx->setPlaceholder('page_message', $page_message);
$modx->setPlaceholder('total_row_count', $transaction_array['TOTAL']);

// Insert the order rows.
$modx->setPlaceholder('order_rows', $order_rows_output);

// Build an array with the values to include in the query string.
$url_array = array(
	'many' 					=> $many,
	'search_order_status' 	=> $search_order_status,
	'search_flagged' 		=> $search_flagged,
	'search_start_date' 	=> $search_start_date,
	'search_end_date' 		=> $search_end_date,
	'search_custom_date' 	=> $search_custom_date,
	'global_search' 		=> $global_search,
);
$url_str = genUrlString($url_array);

// Generate the pagination for the order rows.
$order_pagination = createPagination($start, $many, $transaction_array['TOTAL'], $url_str);
$modx->setPlaceholder('order_pagination', $order_pagination);

// Return the final container.
return $modx->getChunk($manager_form_tpl);
?>
